package org.fujene.diskblock.repli;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

import org.fujene.constants.Constants;
import org.fujene.diskblock.DiskBlock;
import org.fujene.memoryblock.MemoryBlock;
import org.fujene.memoryblock.repli.ReplicateInvertIndexBlock;
import org.fujene.structure.InvertIndexData;
import org.fujene.structure.LookupPointer;
import org.fujene.toolbox.ByteConverter;

public class ReplicateInvertIndexDiskBlock extends DiskBlock{
	public ReplicateInvertIndexDiskBlock(File fileDesc) throws Exception{
		super(fileDesc);
	}

	public ReplicateInvertIndexDiskBlock(int ID, File fileDesc, int defaultBodySize, int defaultOptionSize){
		super(ID, fileDesc, Constants.MEMORY_TYPE_INVINDEX, defaultBodySize, defaultOptionSize);
	}

	public ReplicateInvertIndexDiskBlock(ReplicateInvertIndexBlock memBlock, String dir){
		super(memBlock, dir);
	}

	public InvertIndexData getInvertIndex(int ptr) throws IOException{
		if (ptr > this.bodySize - (PTR + IDDIFF + TERMFREQ)) return null;

		RandomAccessFile inputs = null;
		byte[] val = null;
		LookupPointer prevPtr = null;
		long diffID = -1;
		int termfreq = 0;
		try{
			inputs = new RandomAccessFile(fileDesc, "r");
			switch(version){
			case Constants.FINALVER:
				inputs.seek((4 * HEADERLEN) + (4 * optionSize) + ptr);
				val = new byte[PTR];
				inputs.read(val);
				prevPtr = LookupPointer.fromBytes(val);
				if (prevPtr.equals(LookupPointer.EMPTY))
					prevPtr = null;

				val = new byte[IDDIFF];
				inputs.read(val);
				diffID = ByteConverter.byteToLong(val);

				val = new byte[TERMFREQ];
				inputs.read(val);
				termfreq = ByteConverter.byteToInt(val);
				break;

			default:
				break;
			}
		}finally{
			if (inputs != null) inputs.close();
		}

		return new InvertIndexData(prevPtr, diffID, termfreq);
	}

	@Override
	public int toMemory(MemoryBlock memBlock){
		if (memBlock instanceof ReplicateInvertIndexBlock){
			try{
				for(int i = 0; i < ReplicateInvertIndexBlock.OPTSIZE; i++)
					memBlock.setOption(i, this.getOption(i));
				memBlock.setBody(this.getBody(0, this.bodySize), 0);
				memBlock.setBodyVacancy(this.bodyVacancy);
			}catch(Exception e){}
		}
		return this.bodySize - this.bodyVacancy;
	}

	@Override
	public byte[] getData(){
		throw new NoSuchMethodError("Unimplemented method");
	}
}
